package JavaEE.ManyThread4;
import java.util.*;
public class Demo1 {
    public static Object locker1 = new Object();
    public static Object locker2 = new Object();
    // 造成死锁的原因:
    // 1. 同一线程,对一把锁加锁多次 (java的可重入解决)
    // 2. 同一线程,对不同锁加锁(比如此时t1对k2加锁,但k2已经被上锁,并且锁主人不是t1,
    //                      同时t2也要对k1加锁,但k1已经被上锁,锁主人不是t2,则造成死锁)
    // 3. 多个线程,对多个锁加锁(哲学家就餐问题~)(五个哲学家,五个筷子)
    public static void main(String[] args) throws InterruptedException{
        Thread t1 = new Thread(() -> {
            synchronized (locker1){
                try {
                    System.out.println("t1拿到了locker1");
                    // 使t1拿到locker1后阻塞1000ms
                    // 目的是:等待t2成功拿到locker2,否则可能t1直接执行结束,造不成死锁
                    Thread.sleep(1000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                /* 位置1. t1:locker1未解锁时,尝试对locker2加锁,
                   但此时t2因为等待locker1,而进入堵塞状态,造成"谁也不让"的局面,从而死锁
                synchronized (locker2){
                    System.out.println("t1拿到了locker2");
                }*/
            }
            /* 位置2. t1:locker1解锁后,尝试对locker2加锁,
               此时t2如愿拿到locker1,然后同时解开locker1和locker2,于是t1也拿到了locker2*/
            synchronized (locker2){
                System.out.println("t1拿到了locker2");
            }
        });
        Thread t2 = new Thread(() -> {
           synchronized (locker2){
               try {
                   System.out.println("t2拿到了locker2");
                   // 同上
                   Thread.sleep(1000);
               }catch(InterruptedException e){
                   e.printStackTrace();
               }
               synchronized (locker1){
                   System.out.println("t2拿到了locker1");
               }
           }
        });

        t1.start();
        t2.start();
    }
}
